home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 551-575 / disk_562 / intuisup / editor / source.lzh / load.c < prev    next >
C/C++ Source or Header  |  1991-09-22  |  18KB  |  723 lines

  1.         /*************************************
  2.          *                                   *
  3.          *             Editor v1.0           *
  4.          *   by Torsten Jürgeleit in 09/91   *
  5.          *                                   *
  6.          *              Load part            *
  7.          *                                   *
  8.          *************************************/
  9.  
  10.     /* Includes */
  11.  
  12. #include "includes.h"
  13. #include "defines.h"
  14. #include "imports.h"
  15. #include "protos.h"
  16.  
  17.     /* Defines */
  18.  
  19. #define MAX_READ_BUFFER_SIZE    2000
  20. #define MAX_LINE_LEN        80
  21.  
  22. #define BLOCK_TYPE_NONE        0
  23. #define BLOCK_TYPE_HEADER    1
  24. #define BLOCK_TYPE_TEMPLATE    2
  25. #define BLOCK_TYPE_BOX        3
  26. #define BLOCK_TYPE_TEXTATTR    4
  27. #define BLOCK_TYPE_TEXTLIST    5
  28. #define BLOCK_TYPE_BORDERDATA    6
  29. #define BLOCK_TYPE_TEXTDATA    7
  30. #define BLOCK_TYPE_GADGETDATA    8
  31.  
  32. #define HEADER_ITEM_TYPE_LEFTEDGE    1
  33. #define HEADER_ITEM_TYPE_TOPEDGE    2
  34. #define HEADER_ITEM_TYPE_WIDTH        3
  35. #define HEADER_ITEM_TYPE_HEIGHT        4
  36. #define HEADER_ITEM_TYPE_FLAGS        5
  37.  
  38. #define TEMPLATE_ITEM_TYPE_NAME        1
  39. #define TEMPLATE_ITEM_TYPE_TYPE        2
  40. #define TEMPLATE_ITEM_TYPE_FLAGS    3
  41.  
  42. #define BOX_ITEM_TYPE_X1        1
  43. #define BOX_ITEM_TYPE_Y1        2
  44. #define BOX_ITEM_TYPE_X2        3
  45. #define BOX_ITEM_TYPE_Y2        4
  46.  
  47. #define TEXTATTR_ITEM_TYPE_NAME        1
  48. #define TEXTATTR_ITEM_TYPE_YSIZE    2
  49. #define TEXTATTR_ITEM_TYPE_STYLE    3
  50. #define TEXTATTR_ITEM_TYPE_FLAGS    4
  51.  
  52. #define TEXTLIST_ITEM_TYPE_TEXT        1
  53.  
  54. #define BORDERDATA_ITEM_TYPE_TYPE    1
  55.  
  56. #define TEXTDATA_ITEM_TYPE_TYPE        1
  57. #define TEXTDATA_ITEM_TYPE_FLAGS    2
  58. #define TEXTDATA_ITEM_TYPE_TEXT        3
  59.  
  60. #define GADGETDATA_ITEM_TYPE_TYPE    1
  61. #define GADGETDATA_ITEM_TYPE_FLAGS    2
  62. #define GADGETDATA_ITEM_TYPE_TEXT    3
  63. #define GADGETDATA_ITEM_TYPE_SPECIAL1    4
  64. #define GADGETDATA_ITEM_TYPE_SPECIAL2    5
  65. #define GADGETDATA_ITEM_TYPE_SPECIAL3    6
  66.  
  67.     /* Statics */
  68.  
  69. STATIC struct TemplateList  new_template_list;
  70. STATIC struct Template      *new_template;
  71.  
  72. STATIC BYTE *block_keywords[] = {
  73.     "PROJECTHEADER",
  74.     "TEMPLATE",
  75.     "BOX",
  76.     "TEXTATTR",
  77.     "TEXTLIST",
  78.     "BORDERDATA",
  79.     "TEXTDATA",
  80.     "GADGETDATA",
  81.     NULL
  82. };
  83. STATIC BYTE *header_keywords[] = {
  84.     "LEFTEDGE",
  85.     "TOPEDGE",
  86.     "WIDTH",
  87.     "HEIGHT",
  88.     "FLAGS",
  89.     NULL
  90. };
  91. STATIC BYTE *template_keywords[] = {
  92.     "NAME",
  93.     "TYPE",
  94.     "FLAGS",
  95.     NULL
  96. };
  97. STATIC BYTE *box_keywords[] = {
  98.     "X1",
  99.     "Y1",
  100.     "X2",
  101.     "Y2",
  102.     NULL
  103. };
  104. STATIC BYTE *textattr_keywords[] = {
  105.     "NAME",
  106.     "YSIZE",
  107.     "STYLE",
  108.     "FLAGS",
  109.     NULL
  110. };
  111. STATIC BYTE *textlist_keywords[] = {
  112.     "TEXT",
  113.     NULL
  114. };
  115. STATIC BYTE *borderdata_keywords[] = {
  116.     "TYPE",
  117.     NULL
  118. };
  119. STATIC BYTE *textdata_keywords[] = {
  120.     "TYPE",
  121.     "FLAGS",
  122.     "TEXT",
  123.     NULL
  124. };
  125. STATIC BYTE *gadgetdata_keywords[] = {
  126.     "TYPE",
  127.     "FLAGS",
  128.     "TEXT",
  129.     "SPECIAL1",
  130.     "SPECIAL2",
  131.     "SPECIAL3",
  132.     NULL
  133. };
  134.     /* Load project */
  135.  
  136.    SHORT
  137. load_project(USHORT mode)
  138. {
  139.    struct TemplateList   *tl = &template_list, *new_tl = &new_template_list;
  140.    struct Template       *tp;
  141.    struct FileRequester  *freq = project_file_requester;
  142.    struct FileData       *fd;
  143.    BYTE   path[LONG_DSIZE + LONG_FSIZE + 1];
  144.    USHORT len;
  145.    SHORT  status = EDITOR_STATUS_NORMAL;
  146.  
  147.    /* Display ARP file requester and check if user selected cancel */
  148.    freq->fr_FuncFlags &= ~FRF_DoColor;
  149.    if (mode == LOAD_MODE_NORMAL) {
  150.       freq->fr_Hail = PROJECT_LOAD_HAIL_TEXT;
  151.    } else {
  152.       freq->fr_Hail = PROJECT_APPEND_HAIL_TEXT;
  153.    }
  154.    if (FileRequest(freq)) {
  155.  
  156.       /* Prepare file name and project name */
  157.       len = strlen(freq->fr_File) - 4;
  158.       if (Strcmp(freq->fr_File + len, ".tpl")) {
  159.      strcat(freq->fr_File, ".tpl");
  160.       }
  161.       if (mode == LOAD_MODE_NORMAL) {
  162.      strncpy(&new_tl->tl_ProjectName[0], freq->fr_File, (size_t)len);
  163.      new_tl->tl_ProjectName[len] = '\0';
  164.       }
  165.  
  166.       /* Build full path for project file */
  167.       strcpy(&path[0], freq->fr_Dir);
  168.       TackOn(&path[0], freq->fr_File);
  169.  
  170.       /* Open file and write project header */
  171.       if (!(fd = open_file(&path[0]))) {
  172.      status = EDITOR_ERROR_OPEN_FAILED;
  173.       } else {
  174.  
  175.      /* Init new template list */
  176.      NewList(&new_tl->tl_List);
  177.      new_tl->tl_ListEntries     = 0;
  178.      new_tl->tl_BorderTemplates = 0;
  179.      new_tl->tl_TextTemplates   = 0;
  180.      new_tl->tl_GadgetTemplates = 0;
  181.      new_tl->tl_Flags           = DEFAULT_TEMPLATE_LIST_FLAGS;
  182.  
  183.      /* Read all templates */
  184.      while ((status = parse_block(fd, BLOCK_TYPE_NONE, mode)) ==
  185.                               EDITOR_STATUS_NORMAL);
  186.      /* If no error then install and display new template list */
  187.      if (status == EDITOR_STATUS_EOF) {
  188.         if (mode == LOAD_MODE_NORMAL) {
  189.  
  190.            /* Overwrite old template list */
  191.            if ((status = new_project(new_tl->tl_Flags)) ==
  192.                              EDITOR_STATUS_NORMAL) {
  193.           CopyMem((BYTE *)new_tl, (BYTE *)tl, (LONG)
  194.                            sizeof(struct TemplateList));
  195.           /* Copy templates from new to original template list */
  196.           NewList(&tl->tl_List);
  197.           while (tp = (struct Template *)RemHead(&new_tl->tl_List)) {
  198.              AddTail(&tl->tl_List, &tp->tp_Node);
  199.              display_template(tp);
  200.           }
  201.           tl->tl_Flags &= ~TEMPLATE_LIST_FLAG_CHANGED;
  202.            }
  203.         } else {
  204.  
  205.            /* Append new template list to old one */
  206.            while (tp = (struct Template *)RemHead(&new_tl->tl_List)) {
  207.           AddTail(&tl->tl_List, &tp->tp_Node);
  208.           tl->tl_ListEntries++;
  209.           tl->tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
  210.           display_template(tp);
  211.           switch (TEMPLATE_GROUP(tp)) {
  212.              case TEMPLATE_GROUP_BORDER :
  213.             tp->tp_GroupEntryNum = ++tl->tl_BorderTemplates;
  214.             break;
  215.  
  216.              case TEMPLATE_GROUP_TEXT :
  217.             tp->tp_GroupEntryNum = ++tl->tl_TextTemplates;
  218.             break;
  219.  
  220.              case TEMPLATE_GROUP_GADGET :
  221.             tp->tp_GroupEntryNum = ++tl->tl_GadgetTemplates;
  222.             break;
  223.           }
  224.           if (tp->tp_Flags & TEMPLATE_FLAG_DEFAULT_NAME) {
  225.              build_default_template_name(tp);
  226.           }
  227.                   }
  228.         }
  229.         ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L,
  230.             USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_List);
  231.      }
  232.      close_file(fd);
  233.       }
  234.    }
  235.    if (status != EDITOR_STATUS_NORMAL) {
  236.       show_error(status);
  237.    }
  238.    return(status);
  239. }
  240.     /* Parse block of load file */
  241.  
  242.    STATIC SHORT
  243. parse_block(struct FileData  *fd, USHORT block_type, USHORT mode)
  244. {
  245.    struct TemplateList  *tl;
  246.    struct Template      *tp;
  247.    struct Box           *box;
  248.    struct BorderData    *bd;
  249.    struct TextData      *td;
  250.    struct GadgetData    *gd;
  251.    BYTE  c, *keyword, *arg;
  252.    SHORT status = EDITOR_STATUS_NORMAL;
  253.  
  254.    if (block_type == BLOCK_TYPE_TEMPLATE) {
  255.       if (!(new_template = AllocMem((LONG)sizeof(struct Template),
  256.                      (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
  257.      status = EDITOR_ERROR_OUT_OF_MEM;
  258.       } else {
  259.  
  260.      /* Init new template */
  261.      tp = new_template;
  262.      NewList(&tp->tp_TextList);
  263.      tp->tp_Node.ln_Name = &tp->tp_TemplateName[0];
  264.       }
  265.    }
  266.    if (status == EDITOR_STATUS_NORMAL) {
  267.  
  268.       /* Block loop */
  269.       do {
  270.      if ((status = read_line(fd)) == EDITOR_STATUS_NORMAL) {
  271.  
  272.         /* Mark end of keyword */
  273.         keyword = arg = fd->fd_LineBuffer;
  274.         while ((c = *arg++) != ' ' && c != '=' && c != '\0');
  275.         if (c == '\0') {
  276.            status = EDITOR_ERROR_NO_ARGUMENT;
  277.         } else {
  278.  
  279.            /* Strip double quotes from string argument */
  280.            *(arg - 1) = '\0';
  281.            if (*arg == '"') {
  282.           arg++;
  283.           *(arg + (strlen(arg) - 1)) = '\0';
  284.            }
  285.  
  286.            /* Check keyword */
  287.            if (!Strcmp(keyword, "BEGIN")) {
  288.  
  289.           /* Begin new block */
  290.           status = parse_block(fd, search_keyword(arg,
  291.                          &block_keywords[0]), mode);
  292.            } else {
  293.           if (!Strcmp(keyword, "END")) {
  294.  
  295.              /* End current block */
  296.              if (search_keyword(arg, &block_keywords[0]) !=
  297.                                    block_type) {
  298.             status = EDITOR_ERROR_END_WRONG_BLOCK;
  299.              } else {
  300.             status = EDITOR_STATUS_EOB;
  301.              }
  302.           } else {
  303.  
  304.              /* Parse item */
  305.              status = parse_item(block_type, keyword, arg, mode);
  306.           }
  307.            }
  308.         }
  309.      }
  310.       } while (status == EDITOR_STATUS_NORMAL);
  311.       if (status != EDITOR_STATUS_EOB) {
  312.      if (block_type == BLOCK_TYPE_TEMPLATE && new_template) {
  313.         free_template(new_template);
  314.      }
  315.       } else {
  316.      if (block_type == BLOCK_TYPE_TEMPLATE) {
  317.  
  318.         /* Init new template */
  319.         tp  = new_template;
  320.         box = &tp->tp_Box;
  321.         tp->tp_Node.ln_Name = &tp->tp_TemplateName[0];
  322.         switch (TEMPLATE_GROUP(tp)) {
  323.            case TEMPLATE_GROUP_BORDER :
  324.  
  325.           /* Init border template */
  326.           bd                = &tp->tp_Data.tp_BorderData;
  327.           bd->bd_LeftEdge   = box->bo_X1;
  328.           bd->bd_TopEdge    = box->bo_Y1;
  329.           bd->bd_Width      = box->bo_X2 - box->bo_X1 + 1;
  330.           bd->bd_Height     = box->bo_Y2 - box->bo_Y1 + 1;
  331.           (bd + 1)->bd_Type = INTUISUP_DATA_END;
  332.           break;
  333.  
  334.            case TEMPLATE_GROUP_TEXT :
  335.  
  336.           /* Init text template */
  337.           td                = &tp->tp_Data.tp_TextData;
  338.           td->td_LeftEdge   = box->bo_X1;
  339.           td->td_TopEdge    = box->bo_Y1;
  340.           td->td_TextAttr   = &tp->tp_TextAttr;
  341.           (td + 1)->td_Type = INTUISUP_DATA_END;
  342.           break;
  343.            case TEMPLATE_GROUP_GADGET :
  344.  
  345.           /* Init gadget template */
  346.           gd                = &tp->tp_Data.tp_GadgetData;
  347.           gd->gd_LeftEdge   = box->bo_X1;
  348.           gd->gd_TopEdge    = box->bo_Y1;
  349.           gd->gd_Width      = box->bo_X2 - box->bo_X1 + 1;
  350.           gd->gd_Height     = box->bo_Y2 - box->bo_Y1 + 1;
  351.           gd->gd_TextAttr   = &tp->tp_TextAttr;
  352.           (gd + 1)->gd_Type = INTUISUP_DATA_END;
  353.           break;
  354.         }
  355.  
  356.         /* Add new template to list and increment counters */
  357.         tl = &new_template_list;
  358.         AddTail(&tl->tl_List, &tp->tp_Node);
  359.         tl->tl_ListEntries++;
  360.         switch (TEMPLATE_GROUP(tp)) {
  361.            case TEMPLATE_GROUP_BORDER :
  362.           tp->tp_GroupEntryNum = ++tl->tl_BorderTemplates;
  363.           break;
  364.  
  365.            case TEMPLATE_GROUP_TEXT :
  366.           tp->tp_GroupEntryNum = ++tl->tl_TextTemplates;
  367.           break;
  368.  
  369.            case TEMPLATE_GROUP_GADGET :
  370.           tp->tp_GroupEntryNum = ++tl->tl_GadgetTemplates;
  371.            break;
  372.         }
  373.      }
  374.      status = EDITOR_STATUS_NORMAL;
  375.       }
  376.    }
  377.    return(status);
  378. }
  379.     /* Parse block of load file */
  380.  
  381.    STATIC SHORT
  382. parse_item(USHORT block_type, BYTE *keyword, BYTE *arg, USHORT mode)
  383. {
  384.    struct NewWindow     *nwin;
  385.    struct TemplateList  *new_tl;
  386.    struct Template      *tp;
  387.    struct Box           *box;
  388.    struct TextAttr      *ta;
  389.    struct BorderData    *bd;
  390.    struct TextData      *td;
  391.    struct GadgetData    *gd;
  392.    SHORT status = EDITOR_STATUS_NORMAL;
  393.  
  394.    switch (block_type) {
  395.       case BLOCK_TYPE_HEADER :
  396.  
  397.      /* Read header data */
  398.      if (mode == LOAD_MODE_NORMAL) {
  399.         nwin   = &project_new_window;
  400.         new_tl = &new_template_list;
  401.         switch (search_keyword(keyword, &header_keywords[0])) {
  402.            case HEADER_ITEM_TYPE_LEFTEDGE :
  403.           nwin->LeftEdge = Atol(arg);
  404.           break;
  405.  
  406.            case HEADER_ITEM_TYPE_TOPEDGE :
  407.           nwin->TopEdge = Atol(arg);
  408.           break;
  409.  
  410.            case HEADER_ITEM_TYPE_WIDTH :
  411.           nwin->Width = Atol(arg);
  412.           break;
  413.  
  414.            case HEADER_ITEM_TYPE_HEIGHT :
  415.           nwin->Height = Atol(arg);
  416.           break;
  417.  
  418.            case HEADER_ITEM_TYPE_FLAGS :
  419.           new_tl->tl_Flags = Atol(arg);
  420.           break;
  421.         }
  422.      }
  423.      break;
  424.  
  425.       case BLOCK_TYPE_TEMPLATE :
  426.  
  427.      /* Read template data */
  428.      tp = new_template;
  429.      switch (search_keyword(keyword, &template_keywords[0])) {
  430.         case TEMPLATE_ITEM_TYPE_NAME :
  431.            strcpy(&tp->tp_TemplateName[0], arg);
  432.            break;
  433.  
  434.         case TEMPLATE_ITEM_TYPE_TYPE :
  435.            tp->tp_Type = Atol(arg);
  436.            break;
  437.  
  438.         case TEMPLATE_ITEM_TYPE_FLAGS :
  439.            tp->tp_Flags = Atol(arg);
  440.            break;
  441.      }
  442.      break;
  443.  
  444.       case BLOCK_TYPE_BOX :
  445.      
  446.      /* Read box data */
  447.      box = &new_template->tp_Box;
  448.      switch (search_keyword(keyword, &box_keywords[0])) {
  449.         case BOX_ITEM_TYPE_X1 :
  450.            box->bo_X1 = Atol(arg);
  451.            break;
  452.  
  453.         case BOX_ITEM_TYPE_Y1 :
  454.            box->bo_Y1 = Atol(arg);
  455.            break;
  456.  
  457.         case BOX_ITEM_TYPE_X2 :
  458.            box->bo_X2 = Atol(arg);
  459.            break;
  460.  
  461.         case BOX_ITEM_TYPE_Y2 :
  462.            box->bo_Y2 = Atol(arg);
  463.            break;
  464.      }
  465.      break;
  466.  
  467.       case BLOCK_TYPE_TEXTATTR :
  468.      
  469.      /* Read text attribute data */
  470.      ta = &new_template->tp_TextAttr;
  471.      switch (search_keyword(keyword, &textattr_keywords[0])) {
  472.         case TEXTATTR_ITEM_TYPE_NAME :
  473.            status = duplicate_string((BYTE **)&ta->ta_Name, arg);
  474.            break;
  475.  
  476.         case TEXTATTR_ITEM_TYPE_YSIZE :
  477.            ta->ta_YSize = Atol(arg);
  478.            break;
  479.  
  480.         case TEXTATTR_ITEM_TYPE_STYLE :
  481.            ta->ta_Style = Atol(arg);
  482.            break;
  483.  
  484.         case TEXTATTR_ITEM_TYPE_FLAGS :
  485.            ta->ta_Flags = Atol(arg);
  486.            break;
  487.      }
  488.      break;
  489.  
  490.       case BLOCK_TYPE_TEXTLIST :
  491.  
  492.      /* Read text list */
  493.      switch (search_keyword(keyword, &textlist_keywords[0])) {
  494.         case TEXTLIST_ITEM_TYPE_TEXT :
  495.            status = add_template_text_list_entry(new_template, arg);
  496.            break;
  497.      }
  498.      break;
  499.  
  500.       case BLOCK_TYPE_BORDERDATA :
  501.  
  502.      /* Read border data */
  503.      bd = &new_template->tp_Data.tp_BorderData;
  504.      switch (search_keyword(keyword, &borderdata_keywords[0])) {
  505.         case BORDERDATA_ITEM_TYPE_TYPE :
  506.            bd->bd_Type = Atol(arg);
  507.            break;
  508.      }
  509.      break;
  510.  
  511.       case BLOCK_TYPE_TEXTDATA :
  512.  
  513.      /* Read text data */
  514.      td = &new_template->tp_Data.tp_TextData;
  515.      switch (search_keyword(keyword, &textdata_keywords[0])) {
  516.         case TEXTDATA_ITEM_TYPE_TYPE :
  517.            td->td_Type = Atol(arg);
  518.            break;
  519.  
  520.         case TEXTDATA_ITEM_TYPE_FLAGS :
  521.            td->td_Flags = Atol(arg);
  522.            break;
  523.  
  524.         case TEXTDATA_ITEM_TYPE_TEXT :
  525.            if (td->td_Type == TEXT_DATA_TYPE_TEXT) {
  526.           status = duplicate_string(&td->td_Text, arg);
  527.            } else {
  528.           td->td_Text = (BYTE *)Atol(arg);
  529.            }
  530.            break;
  531.      }
  532.      break;
  533.  
  534.       case BLOCK_TYPE_GADGETDATA :
  535.  
  536.      /* Read gadget data */
  537.      tp = new_template;
  538.      gd = &tp->tp_Data.tp_GadgetData;
  539.      switch (search_keyword(keyword, &gadgetdata_keywords[0])) {
  540.         case GADGETDATA_ITEM_TYPE_TYPE :
  541.            gd->gd_Type = Atol(arg);
  542.            break;
  543.  
  544.         case GADGETDATA_ITEM_TYPE_FLAGS :
  545.            gd->gd_Flags = Atol(arg);
  546.            break;
  547.  
  548.         case GADGETDATA_ITEM_TYPE_TEXT :
  549.            if (*arg == '0') {
  550.           gd->gd_Text = NULL;
  551.            } else {
  552.           status = duplicate_string(&gd->gd_Text, arg);
  553.            }
  554.            break;
  555.  
  556.         case GADGETDATA_ITEM_TYPE_SPECIAL1 :
  557.            gd->gd_SpecialData.gd_Data.gd_Data1 = Atol(arg);
  558.            break;
  559.  
  560.         case GADGETDATA_ITEM_TYPE_SPECIAL2 :
  561.            gd->gd_SpecialData.gd_Data.gd_Data2 = Atol(arg);
  562.            break;
  563.  
  564.         case GADGETDATA_ITEM_TYPE_SPECIAL3 :
  565.            switch (gd->gd_Type) {
  566.           case GADGET_DATA_TYPE_BUTTON :
  567.           case GADGET_DATA_TYPE_CHECK :
  568.           case GADGET_DATA_TYPE_INTEGER :
  569.           case GADGET_DATA_TYPE_SLIDER :
  570.           case GADGET_DATA_TYPE_SCROLLER :
  571.           case GADGET_DATA_TYPE_COUNT :
  572.           case GADGET_DATA_TYPE_PALETTE :
  573.              gd->gd_SpecialData.gd_Data.gd_Data3 = (VOID *)Atol(arg);
  574.              break;
  575.           case GADGET_DATA_TYPE_STRING :
  576.              status = duplicate_string((BYTE **)
  577.                  &gd->gd_SpecialData.gd_Data.gd_Data3, arg);
  578.              break;
  579.           case GADGET_DATA_TYPE_MX :
  580.           case GADGET_DATA_TYPE_CYCLE :
  581.              status = build_template_text_array(tp);
  582.              break;
  583.           case GADGET_DATA_TYPE_LISTVIEW :
  584.              gd->gd_SpecialData.gd_ListViewData.gd_ListViewList = &tp->tp_TextList;
  585.              break;
  586.            }
  587.            break;
  588.      }
  589.      break;
  590.    }
  591.    return(status);
  592. }
  593.     /* Search keyword in given list */
  594.  
  595.    STATIC USHORT
  596. search_keyword(BYTE *keyword, BYTE **keyword_list)
  597. {
  598.    BYTE   *word;
  599.    USHORT count = 0, num = 0;
  600.  
  601.    while (word = *keyword_list++) {
  602.       count++;
  603.       if (!Strcmp(word, keyword)) {
  604.      num = count;
  605.      break;
  606.       }
  607.    }
  608.    return(num);
  609. }
  610.     /* Open load file */
  611.  
  612.    STATIC struct FileData *
  613. open_file(BYTE *name)
  614. {
  615.    struct FileData  *fd;
  616.  
  617.    if (fd = AllocMem((LONG)(sizeof(struct FileData) + MAX_READ_BUFFER_SIZE +
  618.                     MAX_LINE_LEN + 1), (LONG)MEMF_PUBLIC)) {
  619.       if (!(fd->fd_Handle = Open(name, (LONG)MODE_OLDFILE))) {
  620.      FreeMem(fd, (LONG)(sizeof(struct FileData) + MAX_READ_BUFFER_SIZE +
  621.                              MAX_LINE_LEN + 1));
  622.      fd = NULL;
  623.       } else {
  624.  
  625.      /* Init file data struct */
  626.      fd->fd_ReadBuffer  = (BYTE *)(fd + 1);
  627.      fd->fd_CurrentPtr  = NULL;
  628.      fd->fd_LineBuffer  = fd->fd_ReadBuffer + MAX_READ_BUFFER_SIZE;
  629.      fd->fd_CurrentLine = 1;
  630.      fd->fd_Status      = EDITOR_STATUS_NORMAL;
  631.       }
  632.    }
  633.    return(fd);
  634. }
  635.     /* Read line from load file */
  636.  
  637.    STATIC SHORT
  638. read_line(struct FileData  *fd)
  639. {
  640.    BYTE c, *ptr, *line;
  641.    LONG len;
  642.  
  643.    /* Fill read buffer */
  644.    if (!(ptr = fd->fd_CurrentPtr) || ptr == fd->fd_EndPtr) {
  645.       ptr = fill_read_buffer(fd);
  646.    }
  647.    if (ptr) {
  648.  
  649.       /* Find start of line */
  650.       while ((c = *ptr) == ' ' || c == '\t' || c == '\n') {
  651.      if (c == '\n') {
  652.         fd->fd_CurrentLine++;
  653.      }
  654.      if (++ptr == fd->fd_EndPtr) {
  655.         if (!(ptr = fill_read_buffer(fd))) {
  656.            break;
  657.         }
  658.      }
  659.       }
  660.    }
  661.    if (ptr) {
  662.  
  663.       /* Copy line from read buffer to line buffer */
  664.       line = fd->fd_LineBuffer;
  665.       len  = 0;
  666.       while ((c = *ptr) != '\n' && c != '\0') {
  667.      if (len >= MAX_LINE_LEN) {
  668.         fd->fd_Status = EDITOR_ERROR_LINE_TOO_LONG;
  669.         ptr           = NULL;
  670.         break;
  671.      } else {
  672.         *line++ = c;
  673.         len++;
  674.         if (++ptr == fd->fd_EndPtr) {
  675.            if (!(ptr = fill_read_buffer(fd))) {
  676.           break;
  677.            }
  678.         }
  679.      }
  680.       }
  681.       if (ptr) {
  682.  
  683.      /* Mark end of string */
  684.      *line++           = '\0';
  685.      fd->fd_CurrentPtr = ptr;
  686.       }
  687.    }
  688.    return(fd->fd_Status);
  689. }
  690.     /* Fill read buffer from load file */
  691.  
  692.    STATIC BYTE *
  693. fill_read_buffer(struct FileData  *fd)
  694. {
  695.    BYTE  *ptr = NULL;
  696.    LONG  len;
  697.    SHORT status;
  698.  
  699.    if ((len = Read(fd->fd_Handle, fd->fd_ReadBuffer, (LONG)
  700.                         MAX_READ_BUFFER_SIZE)) == -1L) {
  701.       status = EDITOR_ERROR_READ_FAILED;
  702.    } else {
  703.       if (!len) {
  704.      status = EDITOR_STATUS_EOF;
  705.       } else {
  706.      fd->fd_CurrentPtr = ptr = fd->fd_ReadBuffer;
  707.      fd->fd_EndPtr     = ptr + len;
  708.      status            = EDITOR_STATUS_NORMAL;
  709.       }
  710.    }
  711.    fd->fd_Status = status;
  712.    return(ptr);
  713. }
  714.     /* Close load file */
  715.  
  716.    STATIC VOID
  717. close_file(struct FileData  *fd)
  718. {
  719.    Close(fd->fd_Handle);
  720.    FreeMem(fd, (LONG)(sizeof(struct FileData) + MAX_READ_BUFFER_SIZE +
  721.                              MAX_LINE_LEN + 1));
  722. }
  723.